package com.youzhi.backend.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.youzhi.backend.dto.OperateLogTypeEnum;
import com.youzhi.backend.entity.OperateLog;
import com.youzhi.backend.entity.Organization;
import com.youzhi.backend.entity.User;
import com.youzhi.backend.mapper.OrganizationMapper;
import com.youzhi.backend.request.OrganizationEditRequest;
import com.youzhi.backend.service.IOperateLogService;
import com.youzhi.backend.service.IOrganizationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youzhi.backend.service.IPagePostPositionProcessor;
import com.youzhi.backend.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门组织表 服务实现类
 * </p>
 *
 * @author xumeng
 * @since 2022-12-10
 */
@Service
public class OrganizationServiceImpl extends ServiceImpl<OrganizationMapper, Organization> implements IOrganizationService {


    @Autowired
    private IUserService userService;

    @Autowired
    private IOperateLogService operateLogService;


    @Override
    public List<Map<String, Object>> listByParentId(Long parentId) {
        List<Organization> organizations = listByParentId0(parentId);
        return addPrincipleName(organizations);
    }


    private List<Organization> listByParentId0(Long parentId) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq(Organization.Fields.parentId, parentId);
        return list(wrapper);
    }


    //负责人名称
    private List<Map<String, Object>> addPrincipleName(List<Organization> list) {
        if (CollUtil.isNotEmpty(list)) {
            List<Map<String, Object>> collect = list.stream().map(e -> BeanUtil.beanToMap(e)).collect(Collectors.toList());

            List<Long> principleIds = collect.stream().map(e -> (Long) e.get("principleId")).collect(Collectors.toList());

            List<User> users = userService.listByIds(principleIds);

            collect.stream().forEach(e -> {
                Object principleId = e.get("principleId");
                for (User user : users) {
                    if (user.getId().equals(principleId)) {
                        e.put("principleName", user.getName());
                        break;
                    }
                }
            });
            return collect;
        }

        return new ArrayList<>();
    }


    @Override
    public void updateOrganization(OrganizationEditRequest request) {

        if (request.getPrincipleId() != null) {
            /**
             * 更新部门负责人相关信息
             *  1,更新用户表的组织id
             *  2,将该用户从原来负责的组织上去除
             */
            updatePrinciple(request);
        }

        Organization organization = new Organization();
        BeanUtil.copyProperties(request, organization);
        organization.setUpdateTime(new Date());
        updateById(organization);

        //添加操作日志
        operateLogService.addOperateLog(OperateLogTypeEnum.edit, "修改" + request.getName() + "组织架构信息", organization.getId().toString());
    }


    @Override
    public void addOrganization(OrganizationEditRequest request) {

        Organization organization = new Organization();
        BeanUtil.copyProperties(request, organization);
        organization.setId(null);
        organization.setUpdateTime(new Date());
        organization.setCreateTime(new Date());
        save(organization);

        //保存之后id会生成写入
        request.setId(organization.getId());

        if (request.getPrincipleId() != null) {
            //更新部门负责人相关信息
            updatePrinciple(request);
        }

        //添加组织架构
        operateLogService.addOperateLog(OperateLogTypeEnum.add, "添加" + organization.getName() + "组织架构", organization.getId().toString());
    }


    public Organization getByName(String name) {
        QueryWrapper<Organization> wrapper = new QueryWrapper<>();
        wrapper.eq(Organization.Fields.name, name);
        return getOne(wrapper);
    }

    @Override
    public void deleteOrganization(Long id) {
        //一级一级的从子集开始删除，
        getAndRemoveChildren(id);

        //添加操作日志
        operateLogService.addOperateLog(OperateLogTypeEnum.delete, "删除组织架构", id.toString());
    }

    @Override
    public Organization getByPrincipleId(Long userId) {
        QueryWrapper<Organization> wrapper = new QueryWrapper<>();
        wrapper.eq(Organization.Fields.principleId, userId);
        return getOne(wrapper);
    }


    @Override
    public void deletePrincipleIdById(Long id) {
        UpdateWrapper<Organization> wrapper = new UpdateWrapper<>();
        wrapper.set(Organization.Fields.principleId, null);
        wrapper.eq(Organization.Fields.id, id);
        update(wrapper);
    }


    @Override
    public void deletePrincipleId(Long principleId) {
        UpdateWrapper<Organization> wrapper = new UpdateWrapper<>();
        wrapper.set(Organization.Fields.principleId, null);
        wrapper.eq(Organization.Fields.principleId, principleId);
        update(wrapper);
    }

    @Override
    public void assignPrincipleId(Long id, Long principleId) {
        UpdateWrapper<Organization> wrapper = new UpdateWrapper<>();
        wrapper.set(Organization.Fields.principleId, principleId);
        wrapper.eq(Organization.Fields.id, id);
        update(wrapper);

        //添加操作日志
        operateLogService.addOperateLog(OperateLogTypeEnum.edit, "指定组织架构负责人", id.toString() + "," + principleId.toString());
    }


    private void getAndRemoveChildren(Long id) {

        List<Organization> organizations = listByParentId0(id);
        if (CollUtil.isNotEmpty(organizations)) {

            for (Organization organization : organizations) {

                getAndRemoveChildren(organization.getId());

            }
        }

        //将自己删除
        removeById(id);

        //删除用户表组织架构字段
        userService.removeOrganizationId(id);

    }


    private void updatePrinciple(OrganizationEditRequest request) {

        //更新用户组织id
        userService.updateUserOrganizationId(request.getId(), request.getPrincipleId());

        QueryWrapper<Organization> wrapper = new QueryWrapper<>();
        wrapper.eq(Organization.Fields.principleId, request.getPrincipleId());
        Organization one = getOne(wrapper);

        //从原来负责的部门移除该用户
        if (one != null && !one.getId().equals(request.getId())) {
            UpdateWrapper<Organization> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set(Organization.Fields.principleId, null);
            updateWrapper.eq(Organization.Fields.id, one.getId());
            update(updateWrapper);
        }


    }


}
